// $codepro.audit.disable oneStatementPerLine, cyclomaticComplexity
/**
 * Resource file - contains logic for resource stuff.
 */
package edu.gatech.spacetraderteam3.model;

/**
 * Base resource types for use in inventory and such and such.
 * 
 * @author Aaron
 * @version 0.1
 */
public enum Resource {
    WATER(30, 150, 4, 3, 30, 50, 0) { // $codepro.audit.disable numericLiterals
        public int modify(State s, Government g, int before) {
            int after = before;
            switch (s) {
                case DROUGHT:
                    after *= LARGE_INCREASE;
                    break;
                case SURPLUS:
                    after /= MEDIUM_INCREASE;
                    break;
                case RECESSION:
                    after *= MEDIUM_INCREASE;
                    break;
                default:
                    break;
            }

            switch (g) {
                case CAPITALIST:
                    after *= SMALL_INCREASE;
                    break;
                case FEUDAL:
                    after *= SMALL_INCREASE;
                    break;
                case SOCIALIST:
                    after *= SMALL_INCREASE;
                    break;
                default:
                    break;
            }
            return after;
        }
    },
    FUR(250, 100, 10, 10, 230, 280, 0) { // $codepro.audit.disable numericLiterals
        public int modify(State s, Government g, int before) {
            int after = before;
            switch (s) {
                case FAMINE:
                    after *= MEDIUM_INCREASE;
                    break;
                case SURPLUS:
                    after /= MEDIUM_INCREASE;
                    break;
                case RECESSION:
                    after *= MEDIUM_INCREASE;
                    break;
                case COLDSPELL:
                    after *= LARGE_INCREASE;
                    break;
                case PLAGUE:
                    after *= MEDIUM_INCREASE;
                    break;
                default:
                    break;
            }

            switch (g) {
                case CAPITALIST:
                    after *= SMALL_INCREASE;
                    break;
                case FEUDAL:
                    after *= SMALL_INCREASE;
                    break;
                default:
                    break;
            }
            return after;
        }
    },
    FOOD(100, 200, 5, 5, 90, 160, 1) { // $codepro.audit.disable numericLiterals
        public int modify(State s, Government g, int before) {
            int after = before;
            switch (s) {
                case FAMINE:
                    after *= LARGE_INCREASE;
                    break;
                case SURPLUS:
                    after /= MEDIUM_INCREASE;
                    break;
                case RECESSION:
                    after *= MEDIUM_INCREASE;
                    break;
                case COLDSPELL:
                    after *= MEDIUM_INCREASE;
                    break;
                default:
                    break;
            }

            switch (g) {
                case ANARCHY:
                    after *= SMALL_INCREASE;
                    break;
                case DICTATORSHIP:
                    after *= SMALL_INCREASE;
                    break;
                case PACIFIST:
                    after *= SMALL_INCREASE;
                    break;
                case SATORI:
                    after /= SMALL_INCREASE;
                    break;
                default:
                    break;
            }
            return after;
        }
    },
    ORE(350, 400, 10, 20, 350, 420, 2) { // $codepro.audit.disable numericLiterals
        public int modify(State s, Government g, int before) {
            int after = before;
            switch (s) {
                case WAR:
                    after *= LARGE_INCREASE;
                    break;
                default:
                    break;

            }

            switch (g) {
                case COMMUNIST:
                    after *= SMALL_INCREASE;
                    break;
                case CYBERNETIC:
                    after *= SMALL_INCREASE;
                    break;
                case TECHNOCRACY:
                    after *= SMALL_INCREASE;
                    break;
                default:
                    break;
            }
            return after;
        }
    },
    GAMES(250, 250, 5, -10, 160, 270, 3) { // $codepro.audit.disable numericLiterals
        public int modify(State s, Government g, int before) {
            int after = before;
            switch (s) {
                case BORED:
                    after *= LARGE_INCREASE;
                    break;
                case SURPLUS:
                    after *= MEDIUM_INCREASE;
                    break;
                case BUSY:
                    after /= MEDIUM_INCREASE;
                    break;
                default:
                    break;
            }

            switch (g) {
                case CAPITALIST:
                    after *= SMALL_INCREASE;
                    break;
                case COMMUNIST:
                    after /= SMALL_INCREASE;
                    break;
                case DICTATORSHIP:
                    after /= SMALL_INCREASE;
                    break;
                case TECHNOCRACY:
                    after *= SMALL_INCREASE;
                    break;
                default:
                    break;
            }
            return after;
        }
    },
    FIREARMS(1250, 350, 100, -75, 600, 1100, 3) { // $codepro.audit.disable
                                                  // numericLiterals
        public int modify(State s, Government g, int before) {
            int after = before;
            switch (s) {
                case WAR:
                    after *= LARGE_INCREASE;
                    break;
                case PEACE:
                    after /= LARGE_INCREASE;
                    break;
                case NOWORKERS:
                    after *= MEDIUM_INCREASE;
                    break;
                default:
                    break;
            }

            switch (g) {
                case FEUDAL:
                    after *= SMALL_INCREASE;
                    break;
                case CONFEDERACY:
                    after *= SMALL_INCREASE;
                    break;
                case MILITARY:
                    after *= SMALL_INCREASE;
                    break;
                case PACIFIST:
                    after /= SMALL_INCREASE;
                    break;
                case SATORI:
                    after /= SMALL_INCREASE;
                    break;
                case THEOCRACY:
                    after /= SMALL_INCREASE;
                    break;
                default:
                    break;
            }
            return after;
        }
    },
    MEDICINE(650, 100, 10, -20, 400, 700, 4) { // $codepro.audit.disable numericLiterals
        public int modify(State s, Government g, int before) {
            int after = before;
            switch (s) {
                case COLDSPELL:
                    after *= MEDIUM_INCREASE;
                    break;
                case PLAGUE:
                    after *= LARGE_INCREASE;
                    break;
                default:
                    break;
            }

            switch (g) {
                case ANARCHY:
                    after *= SMALL_INCREASE;
                    break;
                case DICTATORSHIP:
                    after *= SMALL_INCREASE;
                    break;
                case MONARCHY:
                    after *= SMALL_INCREASE;
                    break;
                case THEOCRACY:
                    after *= SMALL_INCREASE;
                    break;
                case SATORI:
                    after /= SMALL_INCREASE;
                    break;
                case CYBERNETIC:
                    after /= SMALL_INCREASE;
                    break;
                case TECHNOCRACY:
                    after /= SMALL_INCREASE;
                    break;
                default:
                    break;
            }
            return after;
        }
    },
    MACHINES(900, 700, 5, -30, 600, 800, 4) { // $codepro.audit.disable numericLiterals
        public int modify(State s, Government g, int before) {
            int after = before;
            switch (s) {
                case WAR:
                    after *= MEDIUM_INCREASE;
                    break;
                case NOWORKERS:
                    after *= LARGE_INCREASE;
                    break;
                default:
                    break;
            }

            switch (g) {
                case CYBERNETIC:
                    after *= SMALL_INCREASE;
                    break;
                case TECHNOCRACY:
                    after *= SMALL_INCREASE;
                    break;
                case CORPORATE:
                    after *= SMALL_INCREASE;
                    break;
                case COMMUNIST:
                    after /= SMALL_INCREASE;
                    break;
                case SOCIALIST:
                    after /= SMALL_INCREASE;
                    break;
                case SATORI:
                    after /= SMALL_INCREASE;
                    break;
                default:
                    break;
            }
            return after;
        }
    },
    NARCOTICS(3500, 100, 150, -125, 2000, 3000, 5) { // $codepro.audit.disable
                                                     // numericLiterals
        public int modify(State s, Government g, int before) {
            int after = before;
            switch (s) {
                case BORED:
                    after *= LARGE_INCREASE;
                    break;
                case BUSY:
                    after *= MEDIUM_INCREASE;
                    break;
                case RECESSION:
                    after /= MEDIUM_INCREASE;
                    break;
                case SURPLUS:
                    after *= MEDIUM_INCREASE;
                    break;
                default:
                    break;
            }

            switch (g) {
                case ANARCHY:
                    after *= SMALL_INCREASE;
                    break;
                case DEMOCRACY:
                    after *= SMALL_INCREASE;
                    break;
                case THEOCRACY:
                    after /= SMALL_INCREASE;
                    break;
                case PACIFIST:
                    after /= SMALL_INCREASE;
                    break;
                case SATORI:
                    after /= SMALL_INCREASE;
                    break;
                default:
                    break;
            }
            return after;
        }
    },
    ROBOTS(5000, 1000, 100, -150, 3500, 5000, 6) { // $codepro.audit.disable
                                                   // numericLiterals
        public int modify(State s, Government g, int before) {
            int after = before;
            switch (s) {
                case NOWORKERS:
                    after *= LARGE_INCREASE;
                    break;
                case FAMINE:
                    after *= MEDIUM_INCREASE;
                    break;
                case DROUGHT:
                    after *= MEDIUM_INCREASE;
                    break;
                case BUSY:
                    after *= MEDIUM_INCREASE;
                    break;
                default:
                    break;

            }

            switch (g) {
                case TECHNOCRACY:
                    after *= SMALL_INCREASE;
                    break;
                case CYBERNETIC:
                    after *= SMALL_INCREASE;
                    break;
                case CONFEDERACY:
                    after /= SMALL_INCREASE;
                    break;
                case COMMUNIST:
                    after /= SMALL_INCREASE;
                    break;
                case SOCIALIST:
                    after *= SMALL_INCREASE;
                    break;
                case SATORI:
                    after *= SMALL_INCREASE;
                    break;
                default:
                    break;
            }
            return after;
        }
    };

    /**
     * Integers used in resource manipulations and calculations
     */
    private final int basePrice, weight, variance, ipl, min, max, minTech;

    /**
     * Constant to dictate effects of state changes
     */
    private static final double LARGE_INCREASE = 2.0;

    /**
     * Constant to dictate effects of state changes
     */
    private static final double MEDIUM_INCREASE = 1.5;

    /**
     * Constant to dictate effects of state changes
     */
    private static final double SMALL_INCREASE = 1.1;

    /**
     * Constructor for Resource. Assigns values to each resource.
     * 
     * @param basePrice
     *            Base price of good
     * @param weight
     *            Weight of good
     * @param variance
     *            Price variance of good
     * @param ipl
     *            Increase Per TechLevel
     * @param min
     *            Minimum price
     * @param max
     *            Maximum price
     * @param tech
     *            Minimum tech level you're able to sell this resource to.
     */
    private Resource(int basePrice, int weight, int variance, int ipl, int min, int max,
            int tech) {
        this.basePrice = basePrice;
        this.weight = weight;
        this.variance = variance;
        this.ipl = ipl;
        this.min = min;
        this.max = max;
        this.minTech = tech;
    }

    /**
     * Getter for basePrice.
     * 
     * @return The base price.
     */
    public int basePrice() {
        return this.basePrice;
    }

    /**
     * Getter for weight.
     * 
     * @return The weight.
     */
    public int weight() {
        return this.weight;
    }

    /**
     * Getter for price variance.
     * 
     * @return The price variance.
     */
    public int variance() {
        return this.variance;
    }

    /**
     * Getter for Increase Per TechLevel.
     * 
     * @return The Increase Per TechLevel.
     */
    public int ipl() {
        return this.ipl;
    }

    /**
     * Getter for min price.
     * 
     * @return The min price.
     */
    public int min() {
        return this.min;
    }

    /**
     * Getter for max price.
     * 
     * @return The max price.
     */
    public int max() {
        return this.max;
    }

    /**
     * Getter for minimum TechLevel sellable to.
     * 
     * @return The min TechLevel.
     */
    public int minTech() {
        return this.minTech;
    }

    /**
     * Method that modifies the price of a good based on State and Government.
     * 
     * @param s
     *            State
     * @param g
     *            Government
     * @param before
     *            The price of the good before
     * @return Price of the resource modified by State and Gov.
     */
    public abstract int modify(State s, Government g, int before);

    /**
     * Gets a random Resource.
     * 
     * @return A random Resource.
     */
    public static Resource random() {
        return Resource.values()[(int) (Math.random() * Resource.values().length)];
    }

    /**
     * Returns a formatted string representation of the resource name.
     * 
     * @return Formatted resource name
     */
    public String toString() {
        return name().charAt(0) + name().substring(1).toLowerCase();
    }
}
